/**
 * 
 */
package ch14;

import java.applet.Applet;
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Container;
import java.awt.Frame;
import java.awt.Label;
import java.awt.Panel;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

/**
 * @author sz
 *
 * create time：2012-5-17
 */
class TwoCounter2 extends Thread{
	private boolean started = false;
	
	private TextField t1 = new TextField(5),t2  = new TextField(5);
	
	private Label l = new Label("count1 == count2");
	
	private int count1 = 0 , count2 =0;
	
	public TwoCounter2(Container c){
		Panel p = new Panel();
		
		p.add(t1);
		
		p.add(t2);
		
		p.add(l);
		
		c.add(p);
	}
	
	public void start(){
		if(!started){
			started = true;
			super.start();
		}
	}
	
	public  void run(){
		while(true){
			
			synchronized(this){
				t1.setText(Integer.toString(count1++));
				t2.setText(Integer.toString(count2++));
				
				System.out.println(getClass().getName()+count1 +"and"+ count2);
			}
			try{
				System.out.println(this+"-----------------------");
				sleep(500);
			}catch(InterruptedException e){}
		}
	}
	
	public synchronized void synchTest(int i){
		System.out.println("synchTest("+i+")-------");
		Sharing2.incrementAccess();
		if(count1 != count2){
			l.setText("Unsynched");
		}
	}
}

class Watcher2 extends Thread{
	private static int i = 0;
	private int j;
	
	private Sharing2 p;
	
	public Watcher2(Sharing2 p){
		
		 System.out.println("Watcher:" + ++i);
		  j=i;
		this.p = p ;
		
		start();
	}
	
	public void run(){
		
		 
		while(true){
			//System.out.println("watcher["+j+"] running");
			for(int i =0; i < p.s.length; i++){
				
				//System.out.println("watcher["+j+"] synchTest["+i+"]");
				p.s[i].synchTest(j);
			}
			try{
				sleep(500);
			}catch(InterruptedException e){}
		}
	}
}

public class Sharing2 extends Applet {
	TwoCounter2[] s;
	
	private static int accessCount = 0;
	
	private static TextField aCount = new TextField("0",10);
	
	public static void incrementAccess(){
		accessCount++;
		aCount.setText(Integer.toString(accessCount));
	}
	
	
	private Button start = new Button("Start"),
	observer = new Button("Observe");
	
	private boolean isApplet = true;
	
	private int numCounters = 0;
	
	private int numObservers = 0;
	
	public void init(){
		
		s = new TwoCounter2[numCounters];
		
		for(int i = 0 ; i < s.length ; i++)
			s[i] = new TwoCounter2(this);
		
		Panel p = new Panel();
		
		start.addActionListener(new StartL());
		
		p.add(start);
		
		observer.addActionListener(new ObserverL());
		
		p.add(observer);
		
		p.add(new Label("Access Count"));
		
		p.add(aCount);
		
		add(p);
	}
	
	class StartL implements ActionListener{

		/* (non-Javadoc)
		 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
		 */
		@Override
		public void actionPerformed(ActionEvent e) {
			// TODO Auto-generated method stub
			for(int i = 0 ; i<s.length;i++)
				s[i].start();
		}
		
	}
	
	class ObserverL implements ActionListener{

		/* (non-Javadoc)
		 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
		 */
		@Override
		public void actionPerformed(ActionEvent e) {
			// TODO Auto-generated method stub
			for(int i =0 ; i < numObservers;i++)
				new Watcher2(Sharing2.this);
		}
		
	}
	
	public static void main(String[] args){
		Sharing2 applet = new Sharing2();
		
		applet.numCounters = 5;
		
		applet.numObservers = 5;
		
		Frame aFrame = new Frame("Shartin2");
		
		aFrame.addWindowListener(
			      new WindowAdapter() {
			        public void windowClosing(WindowEvent e){
			          System.exit(0);
			        }
			      });
			    aFrame.add(applet, BorderLayout.CENTER);
			    aFrame.setSize(350, applet.numCounters *100);
			    applet.init();
			    applet.start();
			    aFrame.setVisible(true);

	}
}
